package belf.migrate.api.table.schema;

import lombok.AllArgsConstructor;
import lombok.Data;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

/** 表的索引元数据 */
public class IndexKey implements Serializable {
    private static final long serialVersionUID = 17L;

    private List<String> columnNames = new ArrayList<>();
    /** 从源表获取的索引名称，可用于目标表创建索引 */
    private String indexName;
    /** 是否创建唯一索引 */
    private boolean unique;
    /** 索引是升序还是降序 */
    private IndexOrder indexOrder;
    /** 索引类别 */
    private IndexType indexType;
    /** 每种数据库个性化的索引类型名称 */
    private String indexTypeName;

    private String tableName;

    public IndexKey() {
    }

    public IndexKey(List<String> columnNames,
                    String indexName,
                    boolean unique,
                    IndexOrder indexOrder,
                    IndexType indexType) {
        this.columnNames = columnNames;
        this.indexName = indexName;
        this.unique = unique;
        this.indexOrder = indexOrder;
        this.indexType = indexType;
    }

    public String getTableName() {
        return tableName;
    }

    public void setTableName(String tableName) {
        this.tableName = tableName;
    }

    public List<String> getColumnNames() {
        return columnNames;
    }

    public void setColumnNames(List<String> columnNames) {
        this.columnNames = columnNames;
    }

    public String getIndexName() {
        return indexName;
    }

    public void setIndexName(String indexName) {
        this.indexName = indexName;
    }

    public boolean isUnique() {
        return unique;
    }

    public void setUnique(boolean unique) {
        this.unique = unique;
    }

    public IndexOrder getIndexOrder() {
        return indexOrder;
    }

    public void setIndexOrder(IndexOrder indexOrder) {
        this.indexOrder = indexOrder;
    }

    public IndexType getIndexType() {
        return indexType;
    }

    public void setIndexType(IndexType indexType) {
        this.indexType = indexType;
    }

    public String getIndexTypeName() {
        return indexTypeName;
    }

    public void setIndexTypeName(String indexTypeName) {
        this.indexTypeName = indexTypeName;
    }

    @Override
    public String toString() {
        return "IndexKey{" +
                "columnNames=" + columnNames +
                ", indexName='" + indexName + '\'' +
                ", unique=" + unique +
                ", indexOrder=" + indexOrder +
                ", indexType=" + indexType +
                ", indexTypeName='" + indexTypeName + '\'' +
                '}';
    }

    public enum IndexOrder {
        ASC("A"),
        DESC("D"),
        NULL("NULL");
        private final String expression;
        IndexOrder(String expression) {
            this.expression = expression;
        }

        public String getExpression() {
            return expression;
        }
    }

    public enum IndexType {
        //参考微软手册：
        //https://learn.microsoft.com/en-us/sql/connect/jdbc/reference/getindexinfo-method-sqlserverdatabasemetadata?view=sql-server-ver16
        INDEX_STATISTIC(0, ""),
        INDEX_CLUSTERED(1, "CLUSTER"),
        INDEX_HASHED(2, "USING HASH"),
        INDEX_OTHER(3, "");

        private final int value;
        private final String expression;

        IndexType(int value, String expression) {
            this.value = value;
            this.expression = expression;
        }

        public int getValue() {
            return value;
        }

        public String getExpression() {
            return expression;
        }

        public static IndexType byValue(int value) {
            switch (value) {
                case 0: return INDEX_STATISTIC;
                case 1: return INDEX_CLUSTERED;
                case 2: return INDEX_HASHED;
                case 3: return INDEX_OTHER;
                default: return INDEX_HASHED;
            }

        }

    }
}
